﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace TTprotons.Crm.JavascriptAudit.Common
{
    public class ImportExportXmlParser
    {
        public ImportExportXmlParser(string xml)
        {
            Javascripts = new List<JavascriptEvent>();
            ParseXml(xml);
        }

        #region Properties

        public bool IsSuccess
        { get; set; }

        public string ErrorMessage
        { get; set; }

        public string EntityName
        { get; set; }

        public int ObjectTypeCode
        { get; set; }

        public List<JavascriptEvent> Javascripts
        { get; set; }

        #endregion

        private void ParseXml(string xml)
        {
            try
            {
                var document = new XmlDocument();
                document.LoadXml(xml);

                // Try to get to the EntityInfo node.
                var topEntityNode = document.FirstChild.FirstChild.FirstChild;
                var entityInfoNode = topEntityNode.SelectSingleNode("EntityInfo");
                var entityNode = entityInfoNode.FirstChild;

                EntityName = entityNode.Attributes["Name"].Value.ToLower();
                ObjectTypeCode = int.Parse(entityNode.SelectSingleNode("ObjectTypeCode").InnerText);

                var formXmlNode = topEntityNode.SelectSingleNode("FormXml");
                var formsNode = formXmlNode.FirstChild;

                foreach (XmlNode formEntityNode in formsNode.ChildNodes)
                {
                    if (!formEntityNode.Name.Equals("entity"))
                        continue;

                    ParseFormEntityXml(formEntityNode);
                }

                IsSuccess = true;
            }
            catch (Exception ex)
            {
                // Log error
                IsSuccess = false;
                ErrorMessage = ex.Message;
            }
        }

        private void ParseFormEntityXml(XmlNode formEntityNode)
        {
            var formFormNode = formEntityNode.FirstChild;
            var formType = GetFormType(formFormNode.Attributes["type"].Value);

            var formEventsNode = formFormNode.SelectSingleNode("events");
            if (formEventsNode != null)
            {
                // Process the form events.
                ProcessFormLevelEvents(formType, formEventsNode);
            }

            var tabsNode = formFormNode.SelectSingleNode("tabs");
            ProcessTabsLevelEvents(formType, tabsNode);
        }

        private void ProcessTabsLevelEvents(FormTypes formType, XmlNode tabsNode)
        {
            foreach (XmlNode tabNode in tabsNode.ChildNodes)
            {
                if (!tabNode.Name.Equals("tab"))
                    continue;

                try
                {
                    var cellNodes = tabNode.SelectNodes("sections/section/rows/row/cell");
                    foreach (XmlNode cellNode in cellNodes)
                    {
                        var labelNode = cellNode.SelectSingleNode("labels/label");
                        var controlNode = cellNode.SelectSingleNode("control");
                        var eventNodes = cellNode.SelectNodes("events/event");

                        var fieldName = labelNode.Attributes["description"].Value;
                        if (string.IsNullOrEmpty(fieldName))
                            continue;

                        var fieldLogicalName = controlNode.Attributes["id"].Value;
                        
                        foreach (XmlNode eventNode in eventNodes)
                        {
                            var javascript = new JavascriptEvent()
                            {
                                EntityName = EntityName,
                                FormType = formType,
                                JavascriptType = JavascriptTypes.Field,
                                EventName = eventNode.Attributes["name"].Value,
                                IsActive = eventNode.Attributes["active"].Value.Equals("true"),
                                JavascriptCode = eventNode.SelectSingleNode("script").InnerText,
                                FieldName = fieldName,
                                FieldLogicalName = fieldLogicalName
                            };

                            Javascripts.Add(javascript);
                        }
                    }
                }
                catch (Exception ex)
                {
                    
                }
            }
        }

        private void ProcessFormLevelEvents(FormTypes formType, XmlNode formEventsNode)
        {
            var eventNodes = formEventsNode.SelectNodes("event");
            if (eventNodes != null && eventNodes.Count > 0)
            {
                foreach (XmlNode eventNode in eventNodes)
                {
                    var javascript = new JavascriptEvent()
                                       {
                                           EntityName = EntityName,
                                           FormType = formType,
                                           JavascriptType = JavascriptTypes.Form,
                                           EventName = eventNode.Attributes["name"].Value,
                                           IsActive = eventNode.Attributes["active"].Value.Equals("true"),
                                           JavascriptCode = eventNode.SelectSingleNode("script").InnerText
                                       };

                    Javascripts.Add(javascript);
                }
            }
        }

        private static FormTypes GetFormType(string formTypeValue)
        {
            return (FormTypes) Enum.Parse(typeof (FormTypes), formTypeValue, true);
        }
    }
}